<template>
  <div ref="container" style="width: 100vw; height: 100vh"></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import * as THREE from 'three'
// 引入 OrbitControls
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

const container = ref(null)
let renderer, scene, camera, animationId, controls

onMounted(() => {
  // 场景
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0xf5f5f5)

  // 相机
  camera = new THREE.PerspectiveCamera(
    60,
    window.innerWidth / window.innerHeight,
    1,
    1000
  )
  camera.position.set(0, 120, 180)
  camera.lookAt(0, 0, 0)

  // 渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(window.innerWidth, window.innerHeight)
  container.value.appendChild(renderer.domElement)

  // OrbitControls 控件
  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true // 启用阻尼（惯性）
  controls.dampingFactor = 0.05
  controls.enablePan = false // 禁用平移（可选）

  // 地面
  const floorGeometry = new THREE.PlaneGeometry(100, 80)
  const floorMaterial = new THREE.MeshPhongMaterial({
    color: 0xffffff,
    transparent: true,
    opacity: 0.95
  })
  const floor = new THREE.Mesh(floorGeometry, floorMaterial)
  floor.rotation.x = -Math.PI / 2
  scene.add(floor)

  // 墙体参数
  const wallHeight = 10
  const wallThickness = 0.5
  const wallMaterial = new THREE.MeshPhongMaterial({
    color: 0xffffff,
    transparent: true,
    opacity: 0.5
  })

  // 四面墙
  for (let z of [-40, 40]) {
    const wallGeometry = new THREE.BoxGeometry(100, wallHeight, wallThickness)
    const wall = new THREE.Mesh(wallGeometry, wallMaterial)
    wall.position.set(0, wallHeight / 2, z)
    scene.add(wall)
  }
  for (let x of [-50, 50]) {
    const wallGeometry = new THREE.BoxGeometry(wallThickness, wallHeight, 80)
    const wall = new THREE.Mesh(wallGeometry, wallMaterial)
    wall.position.set(x, wallHeight / 2, 0)
    scene.add(wall)
  }

  // 灯光
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.7)
  scene.add(ambientLight)
  const dirLight = new THREE.DirectionalLight(0xffffff, 0.7)
  dirLight.position.set(100, 200, 100)
  scene.add(dirLight)

  // 添加货架
  function createShelf({
    width = 0.8,
    length = 5,
    height = 5,
    layers = 8,
    layerThickness = 0.05,
    color = 0x888888,
    position = { x: 0, y: 0, z: 0 }
  } = {}) {
    const group = new THREE.Group()
    const layerGap = (height - layers * layerThickness) / (layers - 1)
    // 层板
    for (let i = 0; i < layers; i++) {
      const y = (layerThickness / 2) + i * (layerThickness + layerGap)
      const boardGeometry = new THREE.BoxGeometry(length, layerThickness, width)
      const boardMaterial = new THREE.MeshPhongMaterial({ color })
      const board = new THREE.Mesh(boardGeometry, boardMaterial)
      board.position.set(0, y, 0)
      group.add(board)

      // 在每层上放箱子
      // 箱子尺寸：0.4m x 0.3m x 0.4m（长*高*宽），间隔0.2m
      const boxLength = 0.4
      const boxHeight = 0.3
      const boxWidth = 0.4
      const boxGap = 0.2 // 间隔20cm
      const boxColor = 0x3399ff
      // 箱子沿长度和宽度方向排满
      const countX = Math.floor((length + boxGap) / (boxLength + boxGap))
      const countZ = Math.floor((width + boxGap) / (boxWidth + boxGap))
      const totalX = countX * boxLength + (countX - 1) * boxGap
      const totalZ = countZ * boxWidth + (countZ - 1) * boxGap
      const startX = -totalX / 2 + boxLength / 2
      const startZ = -totalZ / 2 + boxWidth / 2
      const boxY = y + layerThickness / 2 + boxHeight / 2

      for (let xi = 0; xi < countX; xi++) {
        for (let zi = 0; zi < countZ; zi++) {
          const boxGeometry = new THREE.BoxGeometry(boxLength, boxHeight, boxWidth)
          const boxMaterial = new THREE.MeshPhongMaterial({ color: boxColor })
          const box = new THREE.Mesh(boxGeometry, boxMaterial)
          box.position.set(
            startX + xi * (boxLength + boxGap),
            boxY,
            startZ + zi * (boxWidth + boxGap)
          )
          group.add(box)
        }
      }
    }
    // 四根立柱
    const poleGeometry = new THREE.BoxGeometry(0.05, height, 0.05)
    const poleMaterial = new THREE.MeshPhongMaterial({ color: 0x444444 })
    const polePositions = [
      [-length / 2 + 0.025, height / 2, -width / 2 + 0.025],
      [ length / 2 - 0.025, height / 2, -width / 2 + 0.025],
      [-length / 2 + 0.025, height / 2,  width / 2 - 0.025],
      [ length / 2 - 0.025, height / 2,  width / 2 - 0.025]
    ]
    for (const [x, y, z] of polePositions) {
      const pole = new THREE.Mesh(poleGeometry, poleMaterial)
      pole.position.set(x, y, z)
      group.add(pole)
    }
    group.position.set(position.x, position.y, position.z)
    return group
  }

  // 在仓库中央添加一个货架，总高度为5米
  const shelf = createShelf({
    width: 0.8,
    length: 5,
    height: 5, // 修改为5米
    layers: 8,
    layerThickness: 0.05,
    position: { x: 0, y: 0, z: 0 }
  })
  scene.add(shelf)

  // 渲染循环
  function animate() {
    animationId = requestAnimationFrame(animate)
    controls.update() // 更新控制器
    renderer.render(scene, camera)
  }
  animate()

  // 响应窗口变化
  window.addEventListener('resize', onWindowResize)
})

onBeforeUnmount(() => {
  cancelAnimationFrame(animationId)
  renderer.dispose()
  window.removeEventListener('resize', onWindowResize)
  controls?.dispose()
})

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
}
</script>